﻿using MiniFox.Caching;
using MiniFox.Components;
using MiniFox.Infrastructure;
using MiniFox.Platform.Applications.Auth;
using MiniFox.Platform.Applications.Models;
using MiniFox.Platform.Applications.Providers;
using MiniFox.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace MiniFox.Platform.Applications.Services
{
    /// <summary>
    /// 
    /// </summary>
    public class OrganizationService : ApiServiceBase, IOrganizationService
    {
        /// <summary>
        /// 
        /// </summary>
        const string SYS_ORG_DEPT = "SYS_ORG_DEPT";
        /// <summary>
        /// 
        /// </summary>
        const string SYS_ORG_DEPT_TREE = "SYS_ORG_DEPT_TREE";
        /// <summary>
        /// 
        /// </summary>
        /// <param name="principal"></param>
        public OrganizationService(SystemPrincipal principal) : base(principal)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        [AutoWired]
        protected IOrganizationProvider OrgProvider
        {
            get;
            set;
        }
        /// <summary>
        /// 
        /// </summary>
        public TreeResultObject<Dept> DeptTreeObject
        {
            get
            {
                return this.Cache.Get($"{SYS_ORG_DEPT_TREE}", () =>
                {
                    var treeObject = new TreeResultObject<Dept>(Depts);
                    return treeObject;
                }, 3600);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="orgId"></param>
        /// <param name="deptId"></param>
        /// <returns></returns>
        public ITreeNode GetDepts(string orgId, string deptId)
        {
            var group = this.DeptTreeObject.TreeGroups[orgId];
            if (string.IsNullOrEmpty(deptId) || string.Equals(orgId, deptId))
                return group.Tree;
            return group.CreateTreeByNodeID(deptId);
        }
        /// <summary>
        /// 获取当前人所在组织机构(超管所有组织机构可见)
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Organization> GetOrganizations()
        {
            IEnumerable<Organization> orgs;
            if (this.Principal.IsAdministrator)
                orgs = this.OrgProvider.GetOrganizations();
            else
                orgs = this.OrgProvider.GetOrganizations(this.Principal.GlobalID);
            return orgs;
        }
        /// <summary>
        /// 
        /// </summary>
        protected IEnumerable<Dept> Depts
        {
            get
            {
                return this.Cache.Get($"{SYS_ORG_DEPT}", () =>
                {
                    var list = this.OrgProvider.GetDepts();
                    return list;
                }, 600);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<Dept> GetUserDepts()
        {
            if (this.Principal.IsAdministrator)
                return this.Depts;

            var arr = this.OrgProvider.GetUserDepts(this.Principal.GlobalID);
            var list = this.Depts.Where(d => arr.Contains(d.DeptPath));
            return list;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<Dept> GetManagedDepts()
        {
            if (this.Principal.IsAdministrator)
                return this.Depts;
            var arr = (from d in this.Depts where d.Director == this.Principal.GlobalID select d.DeptPath).ToArray();
            var list = new List<Dept>();
            arr.ForEach(str =>
            {
                var items = this.Depts.Where(d => d.DeptPath.StartsWith(str));
                list.AddRange(items);
            });
            return list;
        }

        /// <summary>
        /// 获取当前人所在部门(超管所有部门可见)
        /// </summary>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public virtual IEnumerable<Dept> GetUserDepts(string orgId)
        {
            var depts = GetUserDepts();
            if (string.IsNullOrEmpty(orgId))
                return depts;
            return depts.Where(d => d.OrganizationID == orgId);
        }
        /// <summary>
        /// 获取用户在指定机构中所管理的部门及子部门
        /// </summary>
        /// <param name="orgId"></param>
        /// <returns></returns>
        public virtual IEnumerable<Dept> GetManagedDepts(string orgId)
        {
            var depts = GetManagedDepts();
            if (string.IsNullOrEmpty(orgId))
                return depts;
            return depts.Where(d => d.OrganizationID == orgId);
        }
    }
}
